/*
 This file is part of Musimage, a project which makes possible listen to music
 and, at the same time, watch pictures related with that music.
 Copyright (C) 2006  David Garcia Narbona 

 Musimage is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 Musimage is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with Musimage; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package classifyLyrics;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import java.util.Enumeration;
import java.util.Vector;

import weka.classifiers.bayes.NaiveBayes;
import weka.classifiers.meta.FilteredClassifier;
import weka.core.Instances;
import weka.filters.unsupervised.attribute.StringToWordVector;

// Clase que clasifica la letra de las canciones mediante el clasificador
// NaiveBayes proporcionado por WEKA
public class Classify {

	// ** Atributos **///////////////////////////////////////////////

	private BufferedReader trainReader;

	private BufferedReader classifyReader;

	private Instances trainInsts;

	private Instances classifyInsts;

	// Vector de classifyInsts, contiene las clasificaciones de canciones
	// de los idiomas utilizados
	private Vector classifedLyrics;

	private Vector languages;

	// /////////////////////////////////////////////////////////////

	// ** Metodos **////////////////////////////////////////////////

	// Constructor
	public Classify(Vector _languages) {

		classifedLyrics = new Vector();
		languages = _languages;
		process();
	}

	// Getter
	public Vector getClassification() {

		return classifedLyrics;
	}

	private void process() {

		Enumeration e = languages.elements();

		while (e.hasMoreElements()) {

			readArffFile((String) e.nextElement());
			loadData();
			classify();
		}
	}

	// Metodo que lee el archivo ARFF
	private void readArffFile(String language) {

		try {
			trainReader = new BufferedReader(new FileReader(
					".//WEKAFile//trainingWEKA" + language + ".arff"));// File
																		// with
																		// text
																		// examples
			classifyReader = new BufferedReader(new FileReader(
					".//WEKAFile//entradaWEKA" + language + ".arff"));// File
																		// with
																		// text
																		// to
																		// classify
		} catch (FileNotFoundException e) {

			System.err.println("ERROR in Classify class on readArffFile(): "
					+ e.getMessage());
		}
	}

	// Metodo que carga los datos a clasificar en los objetos Instances
	private void loadData() {

		try {
			trainInsts = new Instances(trainReader);
			classifyInsts = new Instances(classifyReader);

			trainInsts.setClassIndex(trainInsts.numAttributes() - 1);
			classifyInsts.setClassIndex(trainInsts.numAttributes() - 1);
		} catch (IOException i) {

			System.err.println("ERROR in Classify class on loadData(): "
					+ i.getMessage());
		}
	}

	private void classify() {

		try {
			FilteredClassifier model = new FilteredClassifier();

			model.setFilter(new StringToWordVector());
			model.setClassifier(new NaiveBayes());

			model.buildClassifier(trainInsts);

			for (int j = 0; j < classifyInsts.numInstances(); j++) {

				classifyInsts.instance(j).setClassMissing();
				double cls = model.classifyInstance(classifyInsts.instance(j));
				classifyInsts.instance(j).setClassValue(cls);
			}

			classifedLyrics.add(classifyInsts.toString());
		} catch (Exception o) {

			System.err.println("ERROR in Classify class on classify(): "
					+ o.getMessage());
		}
	}

	// ///////////////////////////////////////////////////////////////
}
